#include "serialization.h"
#include "items.h"
#include "maps.h"
#include "mapcontroller.h"
#include "character.h"

#include <boost/serialization/string.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/vector.hpp>

template<class Archive>
void TCODColor_S::serialize(Archive & ar, const unsigned int version)
{
	ar & r & g & b;
}

template void TCODColor_S::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version);
template void TCODColor_S::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version);
template void TCODColor_S::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version);

/*************************************************
		Items
*************************************************/
template<class Archive>
void fortress::items::serialize(Archive & ar, const unsigned int version)
{
	ar & boost::serialization::base_object<glyph>(*this);
	ar & name & singular & plural & cost & weight & walkable & canCarry;
	ar & baseDamage.addsub & baseDamage.multiplier & baseDamage.nb_dices & baseDamage.nb_faces;
	ar & color.r & color.b & color.g;
//	ar & events;
}

template void fortress::items::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version);
template void fortress::items::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version);
template void fortress::items::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version);

/*************************************************
		Saved Items
*************************************************/
template<class Archive>
void fortress::savedItems::serialize(Archive & ar, const unsigned int version)
{
	ar & stored;
}

template void fortress::savedItems::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version);
template void fortress::savedItems::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version);
template void fortress::savedItems::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version);

/*************************************************
		Abstract Items
*************************************************/
template<class Archive>
void fortress::abstractItems::serialize(Archive & ar, const unsigned int version)
{
	ar & name & singular & plural & description & cost & weight & walkable & canCarry & transparent & dice & sides & color & glyph;

}

template void fortress::abstractItems::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version);
template void fortress::abstractItems::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version);
template void fortress::abstractItems::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version);


/*************************************************
		Map
*************************************************/
template<class Archive>
void fortress::map::save(Archive & ar, const unsigned int version) const
{
	// I HATE HATE HATE HATE HATE HATE HATE HATE boost's serialization library
	ar & (int)(width);
	ar & (int)(height);
	ar & const_cast<fortress::mapController*>(gameMaps);
	ar & const_cast<std::list<fortress::character*>*>(monsterList);
	ar & const_cast<item_map_t*>(itemMap);
	ar & const_cast<std::map<int,fortress::items*>*>(itemData);
/*	for (int i = 0; i < height; i++)
	{
		for (int j=0; j<width; j++)
		{
			bool a = levelMap->isTransparent(i,j);
			bool b = levelMap->isWalkable(i,j);
			ar & a;
			ar & b;
		}
	}*/
	ar & const_cast<std::vector<std::vector<tile> > *>(drawDataPtr);
	ar & const_cast<std::vector<fortress::portal*> *>(portals);
}

template<class Archive>
void fortress::map::load(Archive & ar, const unsigned int version)
{
	ar & width;
	ar & height;
	ar & gameMaps;
	ar & monsterList;
	ar & itemMap;
	ar & itemData;
	levelMap = new TCODMap(width, height);
	for (int i = 0; i < height; i++)
	{
/*		for (int j=0; j<width;j++)
		{
			bool a,b;
			ar & a;
			ar & b;
			levelMap->setProperties(i,j,a,b);
		}*/
	}
	ar & drawDataPtr;
	ar & portals;
}

template void fortress::map::save<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version)const;
template void fortress::map::save<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version)const;
template void fortress::map::save<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version)const;
template void fortress::map::load<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version);
template void fortress::map::load<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version);
template void fortress::map::load<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version);

/*************************************************
		Map Controller
*************************************************/
template<class Archive>
void fortress::mapController::serialize(Archive & ar, const unsigned int version)
{
	ar & gameMaps;
}

template void fortress::mapController::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version);
template void fortress::mapController::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version);
template void fortress::mapController::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version);

/*************************************************
		Map Tile
*************************************************/
template<class Archive>
void fortress::tile::serialize(Archive & ar, const unsigned int version)
{
	ar & glyph;
	ar & explored;
}

template void fortress::tile::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version);
template void fortress::tile::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version);
template void fortress::tile::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version);


/*************************************************
		Portals
*************************************************/
template<class Archive>
void fortress::portal::serialize(Archive & ar, const unsigned int version)
{
	ar & x & y & type & thisMap & toPortal;
}

template void fortress::portal::serialize<boost::archive::binary_oarchive>(boost::archive::binary_oarchive & ar, const unsigned int version);
template void fortress::portal::serialize<boost::archive::text_oarchive>(boost::archive::text_oarchive & ar, const unsigned int version);
template void fortress::portal::serialize<boost::archive::text_iarchive>(boost::archive::text_iarchive & ar, const unsigned int version);